package com.chuangke.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSONObject;
import com.chuangke.admin.entity.SysLog;
import com.chuangke.admin.service.SysLogService;
import com.chuangke.common.utils.HttpServletRequestUtils;
import com.chuangke.common.utils.HttpUtils;
import com.chuangke.common.utils.SecurityUtils;

/**
 * 系统日志，切面处理类，记录日志
 */
@Aspect
@Component
public class SysLogAspect {

	@Autowired
	private SysLogService sysLogService;

//	@Pointcut("execution(* com.chuangke.*.service.*.*(..))")
//	public void serviceLogPointCut() {
//	}

	@Pointcut("execution(* com.chuangke.*.controller.*.*(..))")
	public void apiLogPointCut() {
	}

//	@Around("serviceLogPointCut()")
//	public Object serviceAround(ProceedingJoinPoint point) throws Throwable {
//		return around(point, SysLog.TYPE_SERVICE);
//	}

	@Around("apiLogPointCut()")
	public Object apiAround(ProceedingJoinPoint point) throws Throwable {
		return around(point, SysLog.TYPE_API);
	}

	private Object around(ProceedingJoinPoint point, String type) throws Throwable {
		long beginTime = System.currentTimeMillis();
		Object result = null;
		try {
			result = point.proceed();
			long time = System.currentTimeMillis() - beginTime;
			saveSysLog(point, time, type);
		} catch (Throwable e) {
			long time = System.currentTimeMillis() - beginTime;
			saveSysLog(point, time, type);
			
			throw e;
		}
		return result;
	}

	private void saveSysLog(ProceedingJoinPoint joinPoint, long time, String type) {
		if (joinPoint.getTarget() instanceof SysLogService) {
			return;
		}

		String userName = SecurityUtils.getUserId();
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();

		SysLog sysLog = new SysLog();
		sysLog.setType(type);
		sysLog.setMethod(joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()");
		sysLog.setParams(getParams(joinPoint));
		sysLog.setIp(HttpServletRequestUtils.getIpAddr(HttpUtils.getHttpServletRequest()));
		sysLog.setUserName(userName);
		sysLog.setCreatedBy(userName);
		sysLog.setUpdatedBy(userName);
		sysLog.setTime(time);

		sysLogService.save(sysLog);
	}

	private String getParams(ProceedingJoinPoint joinPoint) {
		StringBuilder params = new StringBuilder();
		Object[] args = joinPoint.getArgs();
		for (int i = 0; i < args.length; i++) {
			params.append("Param").append(i).append(":");
			try {
				if (args[i] instanceof MultipartFile) {
					params.append("文件上传");
				} else {
					params.append(JSONObject.toJSONString(args[i]));
				}
			} catch (Exception e) {
				params.append("Parse failured!");
			}
			params.append(" ; ");
		}
		return params.length() > 200 ? params.substring(0, 200) + "..." : params.toString();
	}

}
